package com.tidemark.robot;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Date;
import java.util.TimerTask;


import com.google.gdata.client.finance.FinanceService;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;
import com.tidemark.Consts;
import com.tidemark.Proposal;
import com.tidemark.Reader;
import com.tidemark.Stock;
import com.tidemark.StockDataModel;

/**
 * 1 RegularTask operates on 1 portfolio, through FinanceClient 
 * 
 */
public class RegularTask extends TimerTask {

	private FinancePortfoliosClient client;
	private String portfolioTitle;
	
	private Reader[] readers = { new com.ifeng.stock.RelativeReader(),
	/* TODO add more */
	};

	private Proposal[] proposals; // first round propose

	private Proposal actionPlan;// final

	public RegularTask(String portfolioTitle ){
		this.portfolioTitle = portfolioTitle;
	}
	
	
	/**
	 * the main logic of the regular task is:
	 * propose-->discuss-->conclude-->operate
	 */
	@Override
	public void run() {
		if(!isTradeDay()){
			System.out.println("today is holiday: " + new Date());		
			return;
		}
		
		System.out.println("resume work at: " + new Date());
		this.client = new FinancePortfoliosClient(portfolioTitle);
		
		// all Readers give proposals
		proposals = getProposals(readers);

		// discuss proposals
		discuss(readers, proposals);

		// merge discussion results
		actionPlan = merge(proposals);

		// robot operates according to result
		act(actionPlan);
		System.out.println("work done, sleep");
	}

	private boolean isTradeDay() {
		int day = new Date().getDay();
		if (day == 6 || day == 7) {
			return false; // given date is weekend
		}
		// TODO how to check public holidays
		return true;
	}

	
	/**
	 * every reader proposes from scratch
	 * 
	 * @param readers
	 * @return proposals
	 */
	private Proposal[] getProposals(Reader[] readers) {
		Proposal[] pros = new Proposal[readers.length];
		for (int i = 0; i < readers.length; i++) {
			pros[i] = readers[i].propose();
		}
		return pros;
	}

	private void discuss(Reader[] readers, Proposal[] proposals) {
		// TODO, readers add comments to proposals
	}

	private Proposal merge(Proposal[] proposals) {
		return proposals[0];// TODO for test
	}

	/**
	 * use google finance api to operate the account
	 * 
	 * @param actionPlan
	 */
	private void act(Proposal actionPlan) {
		if (actionPlan.getComment() != null) {
			throw new RuntimeException("actionPlan should have no comment");
		}

		StockDataModel data = actionPlan.getData();
		Object[] stocks = data.getAll();
		if (stocks != null) {
			for (int i = 0; i < stocks.length; i++) {
				try {
					client.trade((Stock)stocks[i]);
				} catch (MalformedURLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (ServiceException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		else{
			System.out.println("No action plan now. Wait for next chance.");
		}
	}

}
